<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: Highchart.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: Highchart.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>"use strict";

// Import external names locally
var Shared,
	Collection,
	CollectionInit,
	Overload;

Shared = require('./Shared');
Overload = require('./Overload');

/**
 * The constructor.
 *
 * @constructor
 */
var Highchart = function (collection, options) {
	this.init.apply(this, arguments);
};

Highchart.prototype.init = function (collection, options) {
	this._options = options;
	this._selector = window.jQuery(this._options.selector);

	if (!this._selector[0]) {
		throw(this.classIdentifier() + ' "' + collection.name() + '": Chart target element does not exist via selector: ' + this._options.selector);
	}

	this._listeners = {};
	this._collection = collection;

	// Setup the chart
	this._options.series = [];

	// Disable attribution on highcharts
	options.chartOptions = options.chartOptions || {};
	options.chartOptions.credits = false;

	// Set the data for the chart
	var data,
		seriesObj,
		chartData;

	switch (this._options.type) {
		case 'pie':
			// Create chart from data
			this._selector.highcharts(this._options.chartOptions);
			this._chart = this._selector.highcharts();

			// Generate graph data from collection data
			data = this._collection.find();

			seriesObj = {
				allowPointSelect: true,
				cursor: 'pointer',
				dataLabels: {
					enabled: true,
					format: '&lt;b>{point.name}&lt;/b>: {y} ({point.percentage:.0f}%)',
					style: {
						color: (window.Highcharts.theme &amp;&amp; window.Highcharts.theme.contrastTextColor) || 'black'
					}
				}
			};

			chartData = this.pieDataFromCollectionData(data, this._options.keyField, this._options.valField);

			window.jQuery.extend(seriesObj, this._options.seriesOptions);

			window.jQuery.extend(seriesObj, {
				name: this._options.seriesName,
				data: chartData
			});

			this._chart.addSeries(seriesObj, true, true);
			break;

		case 'line':
		case 'area':
		case 'column':
		case 'bar':
			// Generate graph data from collection data
			chartData = this.seriesDataFromCollectionData(
				this._options.seriesField,
				this._options.keyField,
				this._options.valField,
				this._options.orderBy,
				this._options
			);

			this._options.chartOptions.xAxis = chartData.xAxis;
			this._options.chartOptions.series = chartData.series;

			this._selector.highcharts(this._options.chartOptions);
			this._chart = this._selector.highcharts();
			break;

		default:
			throw(this.classIdentifier() + ' "' + collection.name() + '": Chart type specified is not currently supported by ForerunnerDB: ' + this._options.type);
	}

	// Hook the collection events to auto-update the chart
	this._hookEvents();
};

Shared.addModule('Highchart', Highchart);

Collection = Shared.modules.Collection;
CollectionInit = Collection.prototype.init;

Shared.mixin(Highchart.prototype, 'Mixin.Common');
Shared.mixin(Highchart.prototype, 'Mixin.Events');

/**
 * Gets / sets the current state.
 * @param {String=} val The name of the state to set.
 * @returns {*}
 */
Shared.synthesize(Highchart.prototype, 'state');

/**
 * Generate pie-chart series data from the given collection data array.
 * @param data
 * @param keyField
 * @param valField
 * @returns {Array}
 */
Highchart.prototype.pieDataFromCollectionData = function (data, keyField, valField) {
	var graphData = [],
		i;

	for (i = 0; i &lt; data.length; i++) {
		graphData.push([data[i][keyField], data[i][valField]]);
	}

	return graphData;
};

/**
 * Generate line-chart series data from the given collection data array.
 * @param seriesField
 * @param keyField
 * @param valField
 * @param orderBy
 */
Highchart.prototype.seriesDataFromCollectionData = function (seriesField, keyField, valField, orderBy, options) {
	var data = this._collection.distinct(seriesField),
		seriesData = [],
		xAxis = options &amp;&amp; options.chartOptions &amp;&amp; options.chartOptions.xAxis ? options.chartOptions.xAxis : {
			categories: []
		},
		seriesName,
		query,
		dataSearch,
		seriesValues,
		sData,
		i, k;

	// What we WANT to output:
	/*series: [{
		name: 'Responses',
		data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
	}]*/

	// Loop keys
	for (i = 0; i &lt; data.length; i++) {
		seriesName = data[i];
		query = {};
		query[seriesField] = seriesName;

		seriesValues = [];
		dataSearch = this._collection.find(query, {
			orderBy: orderBy
		});

		// Loop the keySearch data and grab the value for each item
		for (k = 0; k &lt; dataSearch.length; k++) {
			if (xAxis.categories) {
				xAxis.categories.push(dataSearch[k][keyField]);
				seriesValues.push(dataSearch[k][valField]);
			} else {
				seriesValues.push([dataSearch[k][keyField], dataSearch[k][valField]]);
			}
		}

		sData = {
			name: seriesName,
			data: seriesValues
		};

		if (options.seriesOptions) {
			for (k in options.seriesOptions) {
				if (options.seriesOptions.hasOwnProperty(k)) {
					sData[k] = options.seriesOptions[k];
				}
			}
		}

		seriesData.push(sData);
	}

	return {
		xAxis: xAxis,
		series: seriesData
	};
};

/**
 * Hook the events the chart needs to know about from the internal collection.
 * @private
 */
Highchart.prototype._hookEvents = function () {
	var self = this;

	self._collection.on('change', function () {
		self._changeListener.apply(self, arguments);
	});

	// If the collection is dropped, clean up after ourselves
	self._collection.on('drop', function () {
		self.drop.apply(self);
	});
};

/**
 * Handles changes to the collection data that the chart is reading from and then
 * updates the data in the chart display.
 * @private
 */
Highchart.prototype._changeListener = function () {
	var self = this;

	// Update the series data on the chart
	if (typeof self._collection !== 'undefined' &amp;&amp; self._chart) {
		var data = self._collection.find(),
			i;

		switch (self._options.type) {
			case 'pie':
				self._chart.series[0].setData(
					self.pieDataFromCollectionData(
						data,
						self._options.keyField,
						self._options.valField
					),
					true,
					true
				);
				break;

			case 'bar':
			case 'line':
			case 'area':
			case 'column':
				var seriesData = self.seriesDataFromCollectionData(
					self._options.seriesField,
					self._options.keyField,
					self._options.valField,
					self._options.orderBy,
					self._options
				);

				if (seriesData.xAxis.categories) {
					self._chart.xAxis[0].setCategories(
						seriesData.xAxis.categories
					);
				}

				for (i = 0; i &lt; seriesData.series.length; i++) {
					if (self._chart.series[i]) {
						// Series exists, set it's data
						self._chart.series[i].setData(
							seriesData.series[i].data,
							true,
							true
						);
					} else {
						// Series data does not yet exist, add a new series
						self._chart.addSeries(
							seriesData.series[i],
							true,
							true
						);
					}
				}
				break;

			default:
				break;
		}
	}
};

/**
 * Destroys the chart and all internal references.
 * @returns {Boolean}
 */
Highchart.prototype.drop = function (callback) {
	if (!this.isDropped()) {
		this._state = 'dropped';

		if (this._chart) {
			this._chart.destroy();
		}

		if (this._collection) {
			this._collection.off('change', this._changeListener);
			this._collection.off('drop', this.drop);

			if (this._collection._highcharts) {
				delete this._collection._highcharts[this._options.selector];
			}
		}

		delete this._chart;
		delete this._options;
		delete this._collection;

		this.emit('drop', this);

		if (callback) {
			callback(false, true);
		}

		delete this._listeners;

		return true;
	} else {
		return true;
	}
};

// Extend collection with highchart init
Collection.prototype.init = function () {
	this._highcharts = {};
	CollectionInit.apply(this, arguments);
};

/**
 * Creates a pie chart from the collection.
 * @type {Overload}
 */
Collection.prototype.pieChart = new Overload({
	/**
	 * Chart via options object.
	 * @func pieChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'pie';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'pie';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func pieChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {String} seriesName The name of the series to display on the chart.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, keyField, valField, seriesName, options) {
		options = options || {};

		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;
		options.seriesName = seriesName;

		// Call the main chart method
		this.pieChart(options);
	}
});

/**
 * Creates a line chart from the collection.
 * @type {Overload}
 */
Collection.prototype.lineChart = new Overload({
	/**
	 * Chart via selector.
	 * @func lineChart
	 * @memberof Highchart
	 * @param {String} selector The chart selector.
	 * @returns {*}
	 */
	'string': function (selector) {
		return this._highcharts[selector];
	},

	/**
	 * Chart via options object.
	 * @func lineChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'line';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'line';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func lineChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} seriesField The name of the series to plot.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, seriesField, keyField, valField, options) {
		options = options || {};

		options.seriesField = seriesField;
		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;

		// Call the main chart method
		this.lineChart(options);
	}
});

/**
 * Creates an area chart from the collection.
 * @type {Overload}
 */
Collection.prototype.areaChart = new Overload({
	/**
	 * Chart via options object.
	 * @func areaChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'area';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'area';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func areaChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} seriesField The name of the series to plot.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, seriesField, keyField, valField, options) {
		options = options || {};

		options.seriesField = seriesField;
		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;

		// Call the main chart method
		this.areaChart(options);
	}
});

/**
 * Creates a column chart from the collection.
 * @type {Overload}
 */
Collection.prototype.columnChart = new Overload({
	/**
	 * Chart via options object.
	 * @func columnChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'column';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'column';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func columnChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} seriesField The name of the series to plot.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, seriesField, keyField, valField, options) {
		options = options || {};

		options.seriesField = seriesField;
		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;

		// Call the main chart method
		this.columnChart(options);
	}
});

/**
 * Creates a bar chart from the collection.
 * @type {Overload}
 */
Collection.prototype.barChart = new Overload({
	/**
	 * Chart via options object.
	 * @func barChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'bar';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'bar';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func barChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} seriesField The name of the series to plot.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, seriesField, keyField, valField, options) {
		options = options || {};

		options.seriesField = seriesField;
		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;

		// Call the main chart method
		this.barChart(options);
	}
});

/**
 * Creates a stacked bar chart from the collection.
 * @type {Overload}
 */
Collection.prototype.stackedBarChart = new Overload({
	/**
	 * Chart via options object.
	 * @func stackedBarChart
	 * @memberof Highchart
	 * @param {Object} options The options object.
	 * @returns {*}
	 */
	'object': function (options) {
		options.type = 'bar';

		options.chartOptions = options.chartOptions || {};
		options.chartOptions.chart = options.chartOptions.chart || {};
		options.chartOptions.chart.type = 'bar';

		options.plotOptions = options.plotOptions || {};
		options.plotOptions.series = options.plotOptions.series || {};
		options.plotOptions.series.stacking = options.plotOptions.series.stacking || 'normal';

		if (!this._highcharts[options.selector]) {
			// Store new chart in charts array
			this._highcharts[options.selector] = new Highchart(this, options);
		}

		return this._highcharts[options.selector];
	},

	/**
	 * Chart via defined params and an options object.
	 * @func stackedBarChart
	 * @memberof Highchart
	 * @param {String|jQuery} selector The element to render the chart to.
	 * @param {String} seriesField The name of the series to plot.
	 * @param {String} keyField The field to use as the data key.
	 * @param {String} valField The field to use as the data value.
	 * @param {Object} options The options object.
	 */
	'*, string, string, string, ...': function (selector, seriesField, keyField, valField, options) {
		options = options || {};

		options.seriesField = seriesField;
		options.selector = selector;
		options.keyField = keyField;
		options.valField = valField;

		// Call the main chart method
		this.stackedBarChart(options);
	}
});

/**
 * Removes a chart from the page by it's selector.
 * @memberof Collection
 * @param {String} selector The chart selector.
 */
Collection.prototype.dropChart = function (selector) {
	if (this._highcharts &amp;&amp; this._highcharts[selector]) {
		this._highcharts[selector].drop();
	}
};

Shared.finishModule('Highchart');
module.exports = Highchart;</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="ActiveBucket.html">ActiveBucket</a></li><li><a href="Angular.html">Angular</a></li><li><a href="AutoBind.html">AutoBind</a></li><li><a href="Collection.html">Collection</a></li><li><a href="CollectionGroup.html">CollectionGroup</a></li><li><a href="Condition.html">Condition</a></li><li><a href="Core.html">Core</a></li><li><a href="Db.html">Db</a></li><li><a href="Document.html">Document</a></li><li><a href="Grid.html">Grid</a></li><li><a href="Highchart.html">Highchart</a></li><li><a href="Index2d.html">Index2d</a></li><li><a href="IndexBinaryTree.html">IndexBinaryTree</a></li><li><a href="IndexHashMap.html">IndexHashMap</a></li><li><a href="Infinilist.html">Infinilist</a></li><li><a href="KeyValueStore.html">KeyValueStore</a></li><li><a href="Metrics.html">Metrics</a></li><li><a href="MyModule.html">MyModule</a></li><li><a href="NodeApiClient.html">NodeApiClient</a></li><li><a href="NodeApiServer.html">NodeApiServer</a></li><li><a href="NodeRAS.html">NodeRAS</a></li><li><a href="Odm.html">Odm</a></li><li><a href="OldView.html">OldView</a></li><li><a href="Operation.html">Operation</a></li><li><a href="Overload.html">Overload</a></li><li><a href="Overview.html">Overview</a></li><li><a href="Overview_init.html">init</a></li><li><a href="Path.html">Path</a></li><li><a href="Persist.html">Persist</a></li><li><a href="Procedure.html">Procedure</a></li><li><a href="ReactorIO.html">ReactorIO</a></li><li><a href="Section.html">Section</a></li><li><a href="Serialiser.html">Serialiser</a></li><li><a href="Shared.overload.html">overload</a></li><li><a href="View.html">View</a></li></ul><h3>Mixins</h3><ul><li><a href="ChainReactor.html">ChainReactor</a></li><li><a href="Common.html">Common</a></li><li><a href="Constants.html">Constants</a></li><li><a href="Events.html">Events</a></li><li><a href="Matching.html">Matching</a></li><li><a href="Shared.html">Shared</a></li><li><a href="Sorting.html">Sorting</a></li><li><a href="Tags.html">Tags</a></li><li><a href="Triggers.html">Triggers</a></li><li><a href="Updating.html">Updating</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Thu Mar 01 2018 11:34:22 GMT+0000 (GMT)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
